package com.ruoyi.partybuilding.controller;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;


import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.partybuilding.common.DataUtil;
import com.ruoyi.partybuilding.common.DictPB;
import com.ruoyi.partybuilding.common.EQueryController;
import com.ruoyi.partybuilding.common.PageSort;
import com.ruoyi.partybuilding.domain.Honor;
import com.ruoyi.partybuilding.domain.MeetingInfo;
import com.ruoyi.partybuilding.domain.Org;
import com.ruoyi.partybuilding.domain.UserMemberDeptV;
import com.ruoyi.partybuilding.domain.vo.DeptOrgVo;
import com.ruoyi.partybuilding.domain.vo.ScoreYearStatVo;
import com.ruoyi.partybuilding.service.impl.OrgServiceImpl;
import com.ruoyi.partybuilding.service.impl.WorkScoreServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import org.apache.commons.collections4.ListUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.util.function.*;


import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "首页统计信息")
@RestController
@RequestMapping("/partybuilding/IndexPage")
public class IndexPageController extends EQueryController<Org> {

    @Resource
    OrgServiceImpl orgService;

    @Resource
    WorkScoreServiceImpl scoreService;
    //个人
    @ApiOperation(value = "个人统计信息",notes = "t1人员数量,t2组织数量,t3个人积分(-10000表示没查找到积分),t4所在组织荣誉数，t5本人荣誉数")
    @GetMapping(value = "myData")
    public  R<Tuple5<Long,Integer, BigDecimal,Long,Long>> myData() {
        var where = new DeptOrgVo();
        where.setDeptId(getDeptId());
        var deptStat = orgService.deptInfoStat(where);
        var re = deptStat.getData().stream().filter(p -> Objects.equals(p.getDeptId(), getDeptId())).findFirst();
        var memberCount = re.get().getStatMember();
        var orgCount = deptStat.getData().size();
        //
        var mwhere = new ScoreYearStatVo();
        mwhere.setUserId(getUserId());
        mwhere.setYearSign((long)new Date().getYear());
        var mdata=scoreService.memberYearStat(mwhere, new PageSort()).getData();
        var score=mdata.size()>0?mdata.get(0).getScoreSum():new BigDecimal(-10000);
        score=score==null?new BigDecimal(-10000):score;
        //荣誉
        var honorPersonCount = queryHelper.queryable(Honor.class)
                .where(p -> p.eq(Honor::getTeamHonor, 0).eq(Honor::getUserId, getUserId()).ge(Honor::getTypePerson, 0))
                .count();
        var honorOrgCount= queryHelper.queryable(Honor.class)
                .where(p -> p.eq(Honor::getTeamHonor, 1).eq(Honor::getDeptId, getDeptId()).ge(Honor::getTypeOrg, 0))
                .count();
        //
        var tuple = reactor.util.function.Tuples.of(memberCount, orgCount,score,honorOrgCount,honorPersonCount);
        return R.ok(tuple);
    }
    //党员
    @ApiOperation(value = "党员统计信息",notes = "t1总数，t2男性数量，t3三级组织数组[{statMember:部门人数}]")
    @GetMapping(value = "memberStat")
    public R<Tuple3<Long,Long,List<DeptOrgVo>>> memberStat(Long deptId) {
        var baseQuery = queryHelper.queryable(UserMemberDeptV.class)
                .where(p -> p.eq(UserMemberDeptV::getDelFlag, 0).isNotNull(UserMemberDeptV::getId))
                .where(deptId!=null,p->{
                    p.eq(UserMemberDeptV::getDeptId, deptId);
                    p.or().sqlNativeSegment("FIND_IN_SET({0},{1})", x -> x.value(deptId).expression(UserMemberDeptV::getDeptAncestors));
                });
        var manCount = baseQuery.cloneQueryable().where(p -> p.eq(UserMemberDeptV::getSex, 0))
                .selectCount().firstOrNull();
        var allCount= baseQuery.cloneQueryable().selectCount().firstOrNull();
        // 支部人数统计
        var orgType3= ListUtil.of(2l,3,4);
        var deptStat = orgService.deptInfoStat(new DeptOrgVo()).getData();
        var orgs= orgService.deptVoList(null).getData();
        DataUtil.findSet(orgs,deptStat
                ,(p,p1)-> Objects.equals(p.getDeptId(), p1.getDeptId())
                ,(p, p1)->{p.setStatMember(p1.getStatMember());p.setStatTeamPerson(p1.getStatTeamPerson());});

        var lv3List=orgs.stream()
                .filter(p-> p.getType()!=null&&orgType3.contains(p.getType())).collect(Collectors.toList());
        //

        var map=new JSONObject();
        map.put("allCount",allCount);
        map.put("manCount",manCount);
        map.put("lv3list",lv3List);

        return R.ok(Tuples.of(allCount,manCount,lv3List));
    }

    //组织
    //积分
    @ApiOperation(value = "积分统计信息",notes = "t1党员排名,t2组织排名-statMember表示人员数量")
    @GetMapping(value = "ScoreStat")
    public R<Tuple2<List<ScoreYearStatVo>, List<ScoreYearStatVo>>> ScoreStat(Integer year, Integer top) {
        year=year==null?DateUtil.year(new Date()):year;
        top=top==null?5:top;
        //组织排名
        var where = new ScoreYearStatVo();
        where.setYearSign(year.longValue());
        var page = new PageSort();
        page.setPageSize(top);
        page.setOrderByName("scoreSum");
        page.setDescIs(true);
        var orgRank = scoreService.orgYearStat(where, page);
        DataUtil.toMapList(orgRank.getData(), null);
        var deptStat = orgService.deptInfoStat(new DeptOrgVo());
        var orgList=DataUtil.findSetRe(orgRank.getData(), deptStat.getData(),
                (p, p1) -> Objects.equals(p.getDeptId(), p1.getDeptId()),
                (p, p1) -> DataUtil.toMap(p, x -> x.put("statMember", p1.getStatMember()))
        );
        //个人排名
        var memberRank = scoreService.memberYearStat(where, page);
        //
        var map=new JSONObject();
        map.put("memberRank",memberRank.getData());
        map.put("orgRank",orgList);

        return (R)R.ok(Tuples.of(memberRank.getData(),orgList));
    }
    //会议
    @Cacheable(cacheNames = "dataStat" ,keyGenerator = "classMethodKey")
    @ApiOperation(value = "会议统计",notes = "deptId为空则查询所有二级部门,不为空则查询指定部门,返回数组结构[{}],t1党支部党员大会(0),t2支部委员会(1),t3党小组会(2),t4党课(3),t5部门信息对象{}")
    @GetMapping(value = "meetingStat")
    public R<List<Tuple5<Long,Long,Long,Long,DeptOrgVo>>> meetingStat(Long deptId) {
        var mtype0 = DictPB.meeting_type.党支部党员大会.getValue();
        var mtype1 = DictPB.meeting_type.支部委员会.getValue();
        var mtype2 = DictPB.meeting_type.党小组会.getValue();
        var mtype3 = DictPB.meeting_type.党课.getValue();
        var baseQuery = queryHelper.queryable(MeetingInfo.class).where(p -> p.in(MeetingInfo::getStatus, new Long[]{1l, 2l}));
        //
        var depts = orgService.deptVoList(null).getData();
        List<DeptOrgVo> lv2Depts = null;
        if (deptId == null||deptId<1l) {
            lv2Depts = depts.stream().filter(p -> Objects.equals(p.getParentId(), 100l)).collect(Collectors.toList());
        } else
            lv2Depts = depts.stream().filter(p -> Objects.equals(p.getDeptId(), deptId)).collect(Collectors.toList());
        var lv2Childs = new ArrayList<Tuple2<DeptOrgVo, List<DeptOrgVo>>>();
        var resultList = new ArrayList<Tuple5<Long,Long,Long,Long,DeptOrgVo>>();
        for (var lv2Dept : lv2Depts) {
            var lv2Ans = lv2Dept.getAncestors() + "," + lv2Dept.getDeptId();
            var tmp = depts.stream().filter(p -> p.getAncestors().startsWith(lv2Ans)).collect(Collectors.toList());
            lv2Childs.add(Tuples.of(lv2Dept, tmp));
            //
            tmp.add(lv2Dept);
            var ids = tmp.stream().map(p -> p.getDeptId()).collect(Collectors.toList());
            var baseQueryLv2 = baseQuery.cloneQueryable().where(p -> p.in(MeetingInfo::getDeptId, ids));
            var mtype0Count = baseQueryLv2.cloneQueryable().where(p -> p.eq(MeetingInfo::getTypeCode, mtype0)).count();
            var mtype1Count = baseQueryLv2.cloneQueryable().where(p -> p.eq(MeetingInfo::getTypeCode, mtype1)).count();
            var mtype2Count = baseQueryLv2.cloneQueryable().where(p -> p.eq(MeetingInfo::getTypeCode, mtype2)).count();
            var mtype3Count = baseQueryLv2.cloneQueryable().where(p -> p.eq(MeetingInfo::getTypeCode, mtype3)).count();
            resultList.add(Tuples.of(mtype0Count, mtype1Count, mtype2Count, mtype3Count,lv2Dept));
        }

        return R.ok(resultList);
    }
    //荣誉
    public R honorStat() {
        var personCount = queryHelper.queryable(Honor.class)
                .where(p -> p.eq(Honor::getTeamHonor, 0).eq(Honor::getUserId, getUserId()).ge(Honor::getTypePerson, 0))
                .count();
        var orgCount= queryHelper.queryable(Honor.class)
                .where(p -> p.eq(Honor::getTeamHonor, 1).eq(Honor::getDeptId, getDeptId()).ge(Honor::getTypeOrg, 0))
                .count();
        return R.ok();
    }
}
